#include "reporteditor.h"
#include "ui_reporteditor.h"
#include "aboutdialog.h"
#include "../Global/globaldefs.h"
#include "reportwidget.h"
#include "mdisubwindow.h"
#include "srsettingsdialog.h"
#include "../DiagnosticTemplate/diagnostictemplatemodel.h"
#include "../DiagnosticTemplate/diagnostictemplatedelegate.h"

#include <QLocalServer>
#include <QLocalSocket>
#include <QEventLoop>
#include <QIcon>
#include <QMenu>
#include <QSettings>
#include <QDir>
#include <QFileDialog>
#include <QScrollArea>

ReportEditor::ReportEditor(QWidget *parent) :
    currentWindow(0),
    QWidget(parent),
    ui(new Ui::ReportEditor)
{
    ui->setupUi(this);
    setupToolBar();
    setupComponent();
    setupConnection();
    startLocalServer();
}

ReportEditor::~ReportEditor()
{
    delete ui;
}

void ReportEditor::setupToolBar()
{
    QMenu *m;
    QAction *a;
    m = new QMenu(this);
    a = m->addAction(tr("Open folder"), this, SLOT(on_openDirBtn_clicked()));
    a = m->addAction(tr("Open file"), this, SLOT(openFiles()));
    m->addSeparator();
    a = m->addAction(tr("Exit"), this, SLOT(close()));
    ui->openDirBtn->setMenu(m);
    m = new QMenu(this);
    a = m->addAction(tr("Revoke"), this, SLOT(revokeComplete()));
    ui->completeBtn->setMenu(m);
    m = new QMenu(this);
    a = m->addAction(tr("Revoke"), this, SLOT(revokeVerify()));
    ui->verifyBtn->setMenu(m);
    m = new QMenu(this);
    a = m->addAction(tr("Remove Image"), this, SLOT(onRemoveImage()));
    ui->imageBtn->setMenu(m);
    m = new QMenu(this);
    a = m->addAction(tr("Print preview"), this, SLOT(onPrintPreview()));
    ui->printBtn->setMenu(m);
    m = new QMenu(this);
    a = m->addAction(tr("About"), this, SLOT(on_helpBtn_clicked()));
    ui->helpBtn->setMenu(m);
}

void ReportEditor::setupComponent()
{
    server = new QLocalServer(this);
    tempModel = new DiagnosticTemplateModel(this);
    ui->tempView->setModel(tempModel);
    ui->tempView->setItemDelegate(new DiagnosticTemplateDelegate(this));
}

void ReportEditor::setupConnection()
{
    connect(server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));

    connect(ui->mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)),
            this, SLOT(onSubWindowActivated(QMdiSubWindow*)));
    connect(ui->tempView, SIGNAL(doubleClicked(QModelIndex)),
            tempModel, SLOT(onDoubleClicked(QModelIndex)));
    connect(ui->tempView, SIGNAL(newItemAfter(QModelIndex)),
            tempModel, SLOT(onNewItemAfter(QModelIndex)));
    connect(ui->tempView, SIGNAL(newItemBefore(QModelIndex)),
            tempModel, SLOT(onNewItemBefore(QModelIndex)));
    connect(ui->tempView, SIGNAL(newSubItem(QModelIndex)),
            tempModel, SLOT(onNewSubItem(QModelIndex)));
    connect(tempModel, SIGNAL(editItemTitle(QModelIndex)),
            ui->tempView, SLOT(edit(QModelIndex)));
    connect(ui->tempView, SIGNAL(editItem(QModelIndex)),
            tempModel, SLOT(onEditItem(QModelIndex)));
    connect(tempModel, SIGNAL(editItem(QModelIndex,QString,QString,QString)),
            ui->tempView, SLOT(onEditItem(QModelIndex,QString,QString,QString)));
    connect(ui->tempView, SIGNAL(applyEdit(QModelIndex,QString,QString,QString)),
            tempModel, SLOT(onApplyEdit(QModelIndex,QString,QString,QString)));
    connect(ui->tempView, SIGNAL(removeItem(QModelIndex)),
            tempModel, SLOT(onRemoveItem(QModelIndex)));
    connect(tempModel, SIGNAL(itemSelected(QString,QString)),
            this, SLOT(onTemplateItemSelected(QString,QString)));
}

void ReportEditor::openReports(const QStringList &paths)
{
    QStringList pathList = paths;
    QStringList files;

    while (!pathList.isEmpty()) {
        QString p = pathList.takeFirst();
        QDir dir(p);
        if (dir.exists()) {
            QStringList subs = dir.entryList(QDir::Files);
            foreach (const QString &s, subs) {
                files += p + QDir::separator() + s;
            }
            subs = dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot);
            foreach (const QString &s, subs) {
                pathList += p + QDir::separator() + s;
            }
        } else {
            files += p;
        }
    }

    if (files.isEmpty()) return;

    ReportWidget *report = 0;
    QMdiSubWindow *subwin = 0;
    foreach (QString reportFile, files) {
        if (!(subwin = searchReport(reportFile))) {
            report = new ReportWidget;
            report->openReport(reportFile);
            if (report->isReportNormal()) {
                connect(report, SIGNAL(reportClosed(QString)), this, SLOT(onReportClosed(QString)));
                //insertReportImages(report);
                //if (mainWindow->getCurrentGroup().permissions & GP_ModifyReport)
                //    setReadOnly(report->isReportVerified());
                QScrollArea *scroll = new QScrollArea;
                scroll->setWidget(report);
                scroll->setAlignment(Qt::AlignCenter);
                MdiSubWindow *window = new MdiSubWindow;
                window->setWidget(scroll);
                window->setAttribute(Qt::WA_DeleteOnClose);
                ui->mdiArea->addSubWindow(window);
                window->setWindowTitle(report->getReportTitle());
                window->showMaximized();
                currentWindow = window;
            } else {
                delete report;
                report = 0;
            }
        }
    }
    if (subwin) ui->mdiArea->setActiveSubWindow(subwin);

}

bool ReportEditor::isServerListening()
{
    return server->isListening();
}

void ReportEditor::onNewConnection()
{
    QLocalSocket *s = server->nextPendingConnection();
    if (s && s->waitForReadyRead()) {
        QByteArray b = s->readAll();
        QStringList args = QString::fromUtf8(b).split(";", QString::SkipEmptyParts);
        openReports(args);
    }
    s->close();
    s->deleteLater();
}

void ReportEditor::startLocalServer()
{
    QStringList args = QApplication::arguments();
    args.removeFirst();
    QLocalSocket *s = new QLocalSocket;
    connect(s, SIGNAL(disconnected()), s, SLOT(deleteLater()));
    s->connectToServer(QApplication::applicationName());
    if (s->waitForConnected(500)) {
        foreach (const QString &a, args) {
            s->write(a.toUtf8().data());
            s->write(";");
        }
        s->flush();
        QEventLoop l;
        connect(s, SIGNAL(disconnected()), &l, SLOT(quit()));
        l.exec();
    } else {
        server->listen(QApplication::applicationName());
        QStringList dcms;
        foreach (const QString &a, args) {
            dcms += a.split(";", QString::SkipEmptyParts);
        }
        openReports(dcms);
    }
}

void ReportEditor::openFiles()
{
    QSettings s;
    QString p = s.value(OPEN_FILE_PATH).toString();
    QStringList fs = QFileDialog::getOpenFileNames(this, tr("Open dicom files"), p);
    if (!fs.isEmpty()) {
        s.setValue(OPEN_DIR_PATH, fs.first());
        openReports(fs);
    }
}

void ReportEditor::on_openDirBtn_clicked()
{
    QSettings s;
    QString p = s.value(OPEN_DIR_PATH, ".").toString();
    p = QFileDialog::getExistingDirectory(this, tr("Open dicom directory"), p);
    if (!p.isEmpty()) {
        s.setValue(OPEN_DIR_PATH, p);
        openReports(QStringList()<<p);
    }
}

void ReportEditor::on_settingsBtn_clicked()
{
    SRSettingsDialog dialog(this);
    if (QDialog::Accepted == dialog.exec()) {
        QList<QMdiSubWindow*> winList = ui->mdiArea->subWindowList();
        foreach (QMdiSubWindow *win, winList) {
            QScrollArea *scroll = qobject_cast<QScrollArea*>(win->widget());
            ReportWidget *report = qobject_cast<ReportWidget*>(scroll->widget());
            report->reflushReportFormat();
        }
    }
}


void ReportEditor::closeAllReports()
{
    ui->mdiArea->closeAllSubWindows();
    currentWindow = ui->mdiArea->currentSubWindow();
}

void ReportEditor::on_saveBtn_clicked()
{
    if (currentWindow) {
        QScrollArea *scroll = qobject_cast<QScrollArea*>(currentWindow->widget());
        ReportWidget *report = qobject_cast<ReportWidget*>(scroll->widget());
        report->saveReport();
    }
}

void ReportEditor::on_completeBtn_clicked()
{
    if (currentWindow) {
        QScrollArea *scroll = qobject_cast<QScrollArea*>(currentWindow->widget());
        ReportWidget *report = qobject_cast<ReportWidget*>(scroll->widget());
        report->completeReport();
        currentWindow->setWindowTitle(report->getReportTitle());
    }
}

void ReportEditor::on_verifyBtn_clicked()
{
    if (currentWindow) {
        QScrollArea *scroll = qobject_cast<QScrollArea*>(currentWindow->widget());
        ReportWidget *report = qobject_cast<ReportWidget*>(scroll->widget());
        report->verifyReport();
        currentWindow->setWindowTitle(report->getReportTitle());
        setReadOnly(report->isReportVerified());
    }
}

void ReportEditor::revokeComplete()
{

}

void ReportEditor::revokeVerify()
{

}

void ReportEditor::on_imageBtn_clicked()
{

}

void ReportEditor::onRemoveImage()
{

}

void ReportEditor::onRemoveImage(ImageInstance *image)
{

}

void ReportEditor::on_printBtn_clicked()
{
    if (currentWindow) {
        QScrollArea *scroll = qobject_cast<QScrollArea*>(currentWindow->widget());
        ReportWidget *report = qobject_cast<ReportWidget*>(scroll->widget());
        report->print();
    }
}

void ReportEditor::onPrintPreview()
{
    if (currentWindow) {
        QScrollArea *scroll = qobject_cast<QScrollArea*>(currentWindow->widget());
        ReportWidget *report = qobject_cast<ReportWidget*>(scroll->widget());
        report->printPreview();
    }
}

void ReportEditor::on_paperBtn_clicked()
{
    if (currentWindow) {
        QScrollArea *scroll = qobject_cast<QScrollArea*>(currentWindow->widget());
        ReportWidget *report = qobject_cast<ReportWidget*>(scroll->widget());
        report->setReportPaper("");
    }
}

void ReportEditor::onTemplateItemSelected(const QString &findings, const QString &conclusion)
{
    if (currentWindow) {
        QScrollArea *scroll = qobject_cast<QScrollArea*>(currentWindow->widget());
        ReportWidget *report = qobject_cast<ReportWidget*>(scroll->widget());
        report->appendTemplateContents(findings, conclusion);
    }
}

void ReportEditor::onSubWindowActivated(QMdiSubWindow *win)
{/*
    currentWindow = win;
    if (currentWindow) {
        QScrollArea *scroll = qobject_cast<QScrollArea*>(currentWindow->widget());
        ReportWidget *report = qobject_cast<ReportWidget*>(scroll->widget());
        QString paper = report->getReportPaper();
        if (!paper.isEmpty()) ui->paperSizeCombo->setCurrentText(paper);
        if (mainWindow->getCurrentGroup().permissions & GP_ModifyReport)
            setReadOnly(report->isReportVerified());
        thumbnailWidget->setCurrentStudyUid(report->getStudyUid());
    }*/
}


QMdiSubWindow *ReportEditor::searchReport(const QString &file)
{
    QMdiSubWindow *subWin = 0;
    QList<QMdiSubWindow*> winList = ui->mdiArea->subWindowList();
    foreach (QMdiSubWindow *win, winList) {
        QScrollArea *scroll = qobject_cast<QScrollArea*>(win->widget());
        ReportWidget *report = qobject_cast<ReportWidget*>(scroll->widget());
        if (report->getReportFile() == file) {
            subWin = win;
            break;
        }
    }
    return subWin;
}

void ReportEditor::setReadOnly(bool yes)
{
}

bool ReportEditor::setActiveReport(const QString &studyUid)
{
    QMdiSubWindow *subWin = 0;
    QList<QMdiSubWindow*> winList = ui->mdiArea->subWindowList();
    foreach (QMdiSubWindow *win, winList) {
        QScrollArea *scroll = qobject_cast<QScrollArea*>(win->widget());
        ReportWidget *report = qobject_cast<ReportWidget*>(scroll->widget());
        if (report->getStudyUid() == studyUid) {
            subWin = win;
            break;
        }
    }
    if (subWin) {
        ui->mdiArea->setActiveSubWindow(subWin);
        return true;
    } else return false;
}

void ReportEditor::onReportClosed(const QString &uid)
{

}

void ReportEditor::on_helpBtn_clicked()
{
    AboutDialog d(this);
    d.exec();
}

void ReportEditor::on_fullScreenBtn_clicked(bool checked)
{
    if (checked) {
        QRect r = geometry();
        QSettings().setValue("WindowGeometry", r);
        setWindowState(Qt::WindowFullScreen);
        ui->fullScreenBtn->setIcon(QIcon(":/png/full_screen_exit.png"));
    } else {
        QRect r = QSettings().value("WindowGeometry").toRect();
        setWindowState(Qt::WindowNoState);
        if (r.isValid()) this->setGeometry(r);
        ui->fullScreenBtn->setIcon(QIcon(":/png/full_screen.png"));
    }
}
